home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1994 November / Cd Ware (Nro. 2) - Epimundo.iso / DOS / PG / PMAPP.ZIP / STARTUP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-22  |  6.5 KB  |  250 lines

  1. //=====================================================================
  2. //
  3. //  startup.cpp
  4. //
  5. //  program initialization for protected mode Borland C applications
  6. //
  7. //  Copyright (c) 1994, Kevin Morgan, All rights reserved.
  8. //
  9. //=====================================================================
  10. #include <stdio.h>
  11. #include <dos.h>
  12. #include <setjmp.h>
  13. #include "dpmish.h"
  14.  
  15. extern "C" {
  16.     int  _startup( int, char **, char ** );
  17.     void _initialize( void );
  18.     void _cleanup( void );                  /* call #pragma exit routines */
  19.     void abort( void );
  20.  
  21.     void _terminate( int );                 /* terminate program */
  22.     void _checknull( void );                /* check for null pointer usage */
  23.     void _restorezero( void );              /* restore interrupt vectors */
  24.     void _setargv();
  25.     void _setenvp();
  26.  
  27.     char *getenv(char *);
  28.     int  setenv(char *);
  29.  
  30.     int main(...);
  31.     void _exit(int);
  32. }
  33.  
  34.  
  35. int C0argc = 0;
  36.  
  37. char **C0argv = 0;
  38. char **C0environ = 0;
  39. unsigned _psp    = 0;
  40. unsigned monoSeg = 0;
  41. unsigned colrSeg = 0;
  42. unsigned biosSeg = 0;
  43. unsigned _version= 0;
  44. unsigned _osversion = 0;
  45. unsigned char _osminor = 0;
  46. unsigned char _osmajor = 0;
  47.  
  48.  
  49. unsigned _protected = 1;
  50. int     errno = 0;
  51.  
  52. unsigned _RealCvtVector = 0;
  53. unsigned _ScanTodVector[4] = { 0 };
  54.  
  55. static int (far *mainaddr)(...) = main;
  56.  
  57. static int exitCode = 0;
  58.  
  59. static jmp_buf program;
  60.  
  61.  
  62. //=======================================================================
  63. // _startup
  64. // get the program running
  65. //=======================================================================
  66.  
  67. int _startup(int argc, char **argv, char **env)
  68. {
  69.     C0argc = argc;
  70.     C0argv = argv;
  71.     C0environ = env;
  72.  
  73.     asm {
  74.         mov ax, 3000h
  75.         int 21h
  76.         mov _version, ax
  77.         mov _osversion, ax
  78.         mov _osmajor, ah
  79.         mov _osminor, al
  80.     }
  81.  
  82.     {
  83.         DPMI_Regs iregs;
  84.         iregs.eax = 0x5100;     // get PSP
  85.         iregs.reserved = 0;
  86.         iregs.flags = _FLAGS;
  87.         iregs.ss = 0;
  88.         iregs.sp = 0;
  89.         Dpmi.simulateRealInterrupt(0x21, &iregs);
  90.         _psp    = FP_SEG( Dpmi.makeDescriptor(iregs.ebx)   );
  91.     }
  92.  
  93.     // predefine a few selectors we need
  94.     colrSeg = FP_SEG( Dpmi.makeDescriptor(0xb800) );
  95.     monoSeg = FP_SEG( Dpmi.makeDescriptor(0xb000) );
  96.     biosSeg = FP_SEG( Dpmi.makeDescriptor(0x0040) );
  97.  
  98.     _initialize();
  99.     if (setjmp(program)==0)
  100.         exitCode=(*mainaddr)(argc,argv,env);
  101.     _cleanup();
  102.     return exitCode;
  103. }
  104.  
  105. //=======================================================================
  106. // _terminate
  107. // normal program termination
  108. //=======================================================================
  109. void _terminate(int res)
  110. {
  111.     exitCode = res;
  112.     longjmp( program, 1);
  113. }
  114.  
  115. //=======================================================================
  116. // errorDisplay
  117. // display termination message
  118. //=======================================================================
  119. void errorDisplay(char near *msg)
  120. {
  121.     int msglen = 0;
  122.     char near *p = msg;
  123.     while (*p++) msglen++;
  124.     _asm {
  125.             mov     cx, msglen
  126.             mov     dx, msg
  127.             mov     ah, 040h
  128.             mov     bx, 2
  129.             int     021h
  130.     }
  131. }
  132.  
  133. //=======================================================================
  134. // abort
  135. // abnormal program termination
  136. //=======================================================================
  137. void abort()
  138. {
  139.     char near *msg = "Abnormal Termination\r\n";
  140.     errorDisplay(msg);
  141.     _exit(3);
  142. }
  143.  
  144. void _checknull( void ) { }                /* check for null pointer usage */
  145.  
  146. void _restorezero( void ) { }              /* restore interrupt vectors */
  147.  
  148.  
  149. //=======================================================================
  150. // Argv, Envp handling.  Does nothing because our loader takes care of us
  151. //=======================================================================
  152. int _setargv__ = 0;
  153. int _setenvp__ = 0;
  154. void _setargv() { }
  155. void _setenvp() { }
  156.  
  157.  
  158. //=======================================================================
  159. // Startup Table Handling
  160. //=======================================================================
  161.  
  162. const unsigned char PNEAR = 0;
  163. const unsigned char PFAR  = 1;
  164. const unsigned char NOTUSED = 0xff;
  165.  
  166. struct startup_table {
  167.     unsigned char calltype, priority;
  168.     void (far *funcptr)();
  169. };
  170.  
  171. extern startup_table InitStart;
  172. extern startup_table InitEnd;
  173. extern startup_table ExitStart;
  174. extern startup_table ExitEnd;
  175.  
  176.  
  177. void _initialize()
  178. {
  179.     startup_table *st;
  180.     for (;;) {
  181.         startup_table *lowent = 0;
  182.         for (st = &InitStart;st<&InitEnd;st++) {
  183.             if (st->calltype==PFAR||st->calltype==PNEAR) {
  184.                 if (lowent==0)
  185.                     lowent = st;
  186.                 else if (st->priority<lowent->priority) 
  187.                     lowent = st;
  188.             }
  189.             else if (st->calltype!=NOTUSED) {
  190. //                printf("Startup entry: %02x %02x %08lx\n", st->calltype, st->priority, st->funcptr);
  191. //              fflush(stdout);
  192.             }
  193.         }
  194.         if (lowent==0) break;
  195.         switch (lowent->calltype) {
  196.             case PFAR:
  197.                 lowent->calltype = NOTUSED;
  198.                 (*lowent->funcptr)();
  199.                 break;
  200.             case PNEAR:
  201.                 lowent->calltype = NOTUSED;
  202.                 void (near *nfuncptr)();
  203.                 nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
  204.                 (*nfuncptr)();
  205.                 break;
  206.             default:
  207.                 ;
  208.         }
  209.     }
  210. }
  211.  
  212. //=======================================================================
  213. // Cleanup Table Handling
  214. //=======================================================================
  215.  
  216. void _cleanup()
  217. {
  218.     startup_table *st;
  219.     for (;;) {
  220.         startup_table *lowent = 0;
  221.         for (st = &ExitStart;st<&ExitEnd;st++) {
  222.             if (st->calltype==PFAR||st->calltype==PNEAR) {
  223.                 if (lowent==0)
  224.                     lowent = st;
  225.                 else if (st->priority>=lowent->priority) 
  226.                     lowent = st;
  227.             }
  228.             else if (st->calltype!=NOTUSED) {
  229. //                printf("Cleanup entry: %02x %02x %08lx\n", st->calltype, st->priority, st->funcptr);
  230. //              fflush(stdout);
  231.             }
  232.         }
  233.         if (lowent==0) break;
  234.         switch (lowent->calltype) {
  235.             case PFAR:
  236.                 lowent->calltype = NOTUSED;
  237.                 (*lowent->funcptr)();
  238.                 break;
  239.             case PNEAR:
  240.                 lowent->calltype = NOTUSED;
  241.                 void (near *nfuncptr)();
  242.                 nfuncptr = ( void (near *)() ) FP_OFF(lowent->funcptr);
  243.                 (*nfuncptr)();
  244.                 break;
  245.             default:
  246.                 ;
  247.         }
  248.     }
  249. }
  250.